//
// Listing 3: "Visitable" Mock-Objekte
//

#include "interface.h"
#include "consumer.h"

#include <mockpp/VisitableMockObject.h>

#include <exception>
#include <iostream>


class VisitMock : public Interface
                , public MOCKPP_NS::VisitableMockObject
{
  public:

    VisitMock()
      : MOCKPP_NS::VisitableMockObject(MOCKPP_PCHAR("VisitMock"), 0)
      , MOCKPP_CONSTRUCT_MEMBERS_FOR_VOID_VISITABLE_EXT1(open, ext)
      , MOCKPP_CONSTRUCT_MEMBERS_FOR_VISITABLE0(read)
      , MOCKPP_CONSTRUCT_MEMBERS_FOR_VOID_VISITABLE_EXT1(write, ext)
      , MOCKPP_CONSTRUCT_MEMBERS_FOR_VOID_VISITABLE0(close)
    {}

    MOCKPP_VOID_VISITABLE_EXT1(VisitMock, open, const MOCKPP_STD_NS::string &,
                                          ext,  MOCKPP_STD_NS::string);

    MOCKPP_VISITABLE0(VisitMock, MOCKPP_STD_NS::string, read);

    MOCKPP_VOID_VISITABLE_EXT1(VisitMock, write, const MOCKPP_STD_NS::string &,
                                          ext,   MOCKPP_STD_NS::string);

    MOCKPP_VOID_VISITABLE0(VisitMock, close);
};


int main(int argc, char **argv)
{
  try
  {
    VisitMock mock;
    MOCKPP_CONTROLLER_FOR(VisitMock, read) read_controller (&mock);

    // Ablauf beim Einlesen "aufzeichnen"
    mock.open("datei1.lst");
    mock.read();
    mock.read();
    mock.read();
    mock.close();

    // R�ckgabewerte f�r read() eintragen
    read_controller.addReturnValue("Datenpaket-1");
    read_controller.addReturnValue("Datenpaket-2");
    read_controller.addReturnValue("Datenpaket-3");

    // Ablauf beim Zur�ckschreiben "aufzeichnen"
    mock.open("datei1.lst");
    mock.write("Datenpaket-1/fertig");
    mock.write("Datenpaket-2/fertig");
    mock.write("Datenpaket-3/fertig");
    mock.close();

    // Mock-Objekt aktivieren
    mock.activate();

    // Consumer-Klasse ablaufen lassen
    MOCKPP_STD_NS::cout << "Start der Tests" << MOCKPP_STD_NS::endl;

    Consumer consumer(&mock);
    consumer.load();
    consumer.process();
    consumer.save();

    MOCKPP_STD_NS::cout << "Ende der Tests" << MOCKPP_STD_NS::endl;

    // alle restlichen Bedingungen pr�fen
    mock.verify();

    MOCKPP_STD_NS::cout << "Alle Tests wurden fehlerfrei durchlaufen" << MOCKPP_STD_NS::endl;
  }
  catch(MOCKPP_STD_NS::exception &ex)
  {
    MOCKPP_STD_NS::cout << MOCKPP_STD_NS::endl
              << "Fehler aufgetreten.\n" << ex.what() << MOCKPP_STD_NS::endl
              << MOCKPP_STD_NS::endl;
  }
}
